<?php
namespace App\Api\Controllers\Weixin;


use App\Api\Controllers\Weixin\BaseController;
use App\Common\MerchantFuwu;
use App\Common\StoreDayMonthOrder;
use App\Models\Order;
use App\Models\WeixinaStore;
use App\Models\WeixinSharingOrder;
use App\Models\WeixinStore;
use EasyWeChat\Factory;
use EasyWeChat\Payment\Application;
use GuzzleHttp\Psr7;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Log;

class PayController extends BaseController
{

    /**
     * 公众号支付/二维码支付
     * @param $data
     * @param string $trade_type
     * @param string $notify_url
     * @return string
     */
    public function qr_pay($data, $trade_type = "JSAPI", $notify_url = "")
    {
        $out_trade_no = $data['out_trade_no'];
        $config_id = $data['config_id'];
        $store_id = $data['store_id'];
        $merchant_id = $data['merchant_id'];
        $total_amount = $data['total_amount'];
        $shop_price = $data['shop_price'];
        $remark = $data['remark'];
        $device_id = $data['device_id'];
        $shop_name = $data['shop_name'];
        $shop_desc = $data['shop_desc'];
        $goods_detail = $data['goods_detail'];
        $store_name = $data['store_name'];
        $open_id = $data['open_id'];
        $attach = $data['attach'];//原样返回
        $options = $data['options'];
        $wx_sub_merchant_id = $data['wx_sub_merchant_id'];
        $fz_amount = $data['fz_amount'] ?? ''; //分账金额
        $is_profit_sharing = $data['is_profit_sharing'] ?? ''; //是否分账(0-不分;1-分)
        $wx_sharing_rate = $data['wx_sharing_rate'] ?? ''; //分账比例%

        //异步地址
        if ($notify_url == "") {
            $notify_url = url('api/weixin/qr_pay_notify');
        }

        $mch_id = $options['payment']['merchant_id'];
        $appid = $options['app_id'];
        $key = $options['payment']['key'];
        $config = [
            'app_id' => $appid,
            'mch_id' => $mch_id,
            'key' => $key,
            'cert_path' => $options['payment']['cert_path'], // XXX: 绝对路径！！！！
            'key_path' => $options['payment']['key_path'],     // XXX: 绝对路径！！！！
            'sub_mch_id' => $wx_sub_merchant_id,
            // 'device_info'     => '013467007045764',
            // 'sub_app_id'      => '',
            // ...
        ];

        $payment = Factory::payment($config);
        $jssdk = $payment->jssdk;

        $attributes = [
            'trade_type' => $trade_type, // JSAPI，NATIVE，APP...
            'body' => $shop_name,
            'detail' => $shop_desc,
            'out_trade_no' => $out_trade_no,
            'total_fee' => $total_amount * 100,
            'notify_url' => $notify_url, // 支付结果通知网址，如果不设置则会使用配置里的默认地址
            'openid' => $open_id,
            'attach' => $attach, //原样返回
            'device_info' => $device_id,
            'goods_detail' => $goods_detail, //交易详细数据
        ];
        if ($is_profit_sharing && ($wx_sharing_rate > 0)) {
            $attributes['profit_sharing'] = 'Y'; //String，是否指定服务商分账,Y-是，需要分账；N-否，不分账；字母要求大写，不传默认不分账
        }

        $result = $payment->order->unify($attributes);
        if (isset($result['result_code']) && $result['result_code'] == 'FAIL') {
            return json_encode([
                'status' => '2',
                'message' => $result['err_code_des'] ?? '公众号支付/二维码支付error'
            ]);
        }

        if ($result['return_code'] == 'SUCCESS') {
            $json = [];
            //公众号支付
            if ($trade_type == "JSAPI") {
                $prepayId = $result['prepay_id'];
                $json = $jssdk->bridgeConfig($prepayId);
            }

            if ($trade_type == 'NATIVE') {
                $json = $result;
            }

            $data = [
                'status' => 1,
                'out_trade_no' => $out_trade_no,
                'data' => $json
            ];
        } else {
            $data = [
                'status' => 2,
                'out_trade_no' => $out_trade_no,
                "message" => $result['return_msg'],
            ];
        }

        return json_encode($data);
    }


    /**
     * 扫码枪
     * @param $data
     * @return string
     */
    public function scan_pay($data)
    {
        $out_trade_no = $data['out_trade_no'];
        $config_id = $data['config_id'];
        $store_id = $data['store_id'];
        $merchant_id = $data['merchant_id'];
        $total_amount = $data['total_amount'];
        $shop_price = $data['shop_price'];
        $remark = $data['remark'];
        $device_id = $data['device_id'];
        $shop_name = $data['shop_name'];
        $shop_desc = $data['shop_desc'];
        $goods_detail = $data['goods_detail'];
        $store_name = $data['store_name'];
        $auth_code = $data['auth_code'];
        $attach = $data['attach'];//原样返回
        $wx_sub_merchant_id = $data['wx_sub_merchant_id'];
        $options = $data['options'];

        $config = [
            'app_id' => $options['app_id'],
            'mch_id' => $options['payment']['merchant_id'],
            'key' => $options['payment']['key'],
            'cert_path' => $options['payment']['cert_path'], // XXX: 绝对路径！！！！
            'key_path' => $options['payment']['key_path'],     // XXX: 绝对路径！！！！
            'sub_mch_id' => $wx_sub_merchant_id,
            // 'device_info'     => '013467007045764',
            // 'sub_app_id'      => '',
            // ...
        ];
        $payment = Factory::payment($config);

        $attributes = [
            'body' => $shop_name,
            'detail' => $shop_desc,
            'out_trade_no' => $out_trade_no,
            'total_fee' => $total_amount * 100,
            'auth_code' => $auth_code,
            'attach' => $attach,//原样返回
            'device_info' => $device_id,
            'goods_detail' => $goods_detail,//交易详细数据
        ];
        $result = $payment->pay($attributes);

        return $result;
    }


    /**
     * 添加分账接收方
     *
     * 服务商代子商户发起添加分账接收方请求，后续可通过发起分账请求将结算后的钱分到该分账接收方
     * @param $data
     * @return string
     */
    public function profit_sharing_add_receiver($data)
    {
        $config_id = $data['config_id'] ?? '';
        $store_id = $data['store_id'];
        $options = $data['options'];
        $wx_sub_merchant_id = $data['wx_sub_merchant_id'];
        $ways_type = $data['ways_type'] ?? '';

        if ($ways_type == '2000') {
            $wx_store = WeixinStore::where('store_id', $store_id)->first();
            if (!$wx_store) {
                return json_encode([
                    'status' => '2',
                    'message' => '分账接收方资料未设置'
                ]);
            }
        } elseif ($ways_type == '4000') {
            $wx_store = WeixinaStore::where('store_id', $store_id)->first();
            if (!$wx_store) {
                return json_encode([
                    'status' => '2',
                    'message' => '分账接收方资料未设置'
                ]);
            }
        } else {
            return json_encode([
                'status' => '2',
                'message' => '分账接收方资料未设置'
            ]);
        }

        $mch_id = $options['payment']['merchant_id'];
        $appid = $options['app_id'];
        $key = $options['payment']['key'];
        $config = [
            'app_id' => $appid,
            'mch_id' => $mch_id,
            'key' => $key,
            'cert_path' => $options['payment']['cert_path'], // XXX: 绝对路径！！！！
            'key_path' => $options['payment']['key_path'], // XXX: 绝对路径！！！！
            'sub_mch_id' => $wx_sub_merchant_id
        ];

        $receiver = [ //分账接收方对象，json格式
            'type' => $wx_store->wx_sharing_type ?? '', //分账接收方类型(MERCHANT_ID：商户ID；PERSONAL_OPENID：个人openid（由父商户APPID转换得到）；PERSONAL_SUB_OPENID: 个人；sub_openid（由子商户APPID转换得到）)
            'account' => $wx_store->wx_sharing_account ?? '', //分账接收方帐号，类型是MERCHANT_ID时，是商户ID；类型是PERSONAL_OPENID时，是个人openid；类型是PERSONAL_SUB_OPENID时，是个人sub_openid
            'relation_type' => $wx_store->wx_sharing_relation_type ?? '', //与分账方的关系类型，子商户与接收方的关系。本字段值为枚举：SERVICE_PROVIDER：服务商；STORE：门店；STAFF：员工；STORE_OWNER：店主；PARTNER：合作伙伴；HEADQUARTER：总部；BRAND：品牌方；DISTRIBUTOR：分销商；USER：用户；SUPPLIER：供应商；CUSTOM：自定义
        ];
        if ($wx_store->wx_sharing_name) $receiver['name'] = $wx_store->wx_sharing_name; //分账接收方全称,分账接收方类型是MERCHANT_ID时，是商户全称（必传）
        $attributes = [
            'mch_id' => $mch_id, //微信支付分配的商户号
            'sub_mch_id' => $wx_sub_merchant_id, //微信支付分配的子商户号
            'appid' => $appid, //微信分配的公众账号ID
            'nonce_str' => md5(time().rand(1000, 9999)), //随机字符串，不长于32位
            'sign_type' => 'HMAC-SHA256', //签名类型，目前只支持HMAC-SHA256
            'receiver' => json_encode($receiver)
        ];
        $attributes['sign'] = $this->MakeSign($attributes, $key, 'HMAC-SHA256'); //签名
        $result = $this->postXmlCurl($config, $this->ToXml($attributes), 'https://api.mch.weixin.qq.com/pay/profitsharingaddreceiver');
        Log::info('添加分账接收方');
        Log::info(self::xml_to_array($result));
//        array (
//            'return_code' => 'SUCCESS',
//            'result_code' => 'SUCCESS',
//            'mch_id' => '1529340761',
//            'sub_mch_id' => '1603100022',
//            'appid' => 'wx71a6fa53625b7f85',
//            'receiver' => '{"type":"MERCHANT_ID","account":"1529340761","relation_type":"SERVICE_PROVIDER"}',
//            'nonce_str' => '1853b76b0c632515',
//            'sign' => 'BD3DCBC4F92228ABFBB4F91A52ECD64444F7F268792E68D6868D0415BF4B0A17',
//        )
        $result = self::xml_to_array($result);
        if ($result['return_code'] == 'SUCCESS') {
            $result_code = $result['result_code'];

            if ($result_code == 'SUCCESS') {
                $wx_sharing_status = 1;
                $wx_sharing_status_desc = '添加分账接收方,提交申请成功';
            } else {
                $wx_sharing_status = 0;
                $wx_sharing_status_desc = $result['err_code_des'] ?? '添加分账接收方,提交申请成功';
            }

            $json = [
                'result_code' => $result_code, //SUCCESS：添加分账接收方成功；FAIL ：提交业务失败
                'mch_id' => $result['mch_id'] ?? '',
                'sub_mch_id' => $result['sub_mch_id'] ?? '',
                'appid' => $result['appid'] ?? '',
                'receiver' => $result['receiver'] ?? '',
                'nonce_str' => $result['nonce_str'] ?? '',
                'sign' => $result['sign'] ?? ''
            ];

            $data = [
                'status' => 1,
                'data' => $json,
                'message' => $wx_sharing_status_desc
            ];
        } else {
            $wx_sharing_status = 0;
            $wx_sharing_status_desc = $result['return_msg'] ?? '添加分账接收方请求失败';

            $data = [
                'status' => 2,
                'message' => $wx_sharing_status_desc
            ];
        }

        $wx_store_update = [
            'wx_sharing_status' => $wx_sharing_status
        ];
        if ($wx_sharing_status_desc) $wx_store_update['wx_sharing_status_desc'] = $wx_sharing_status_desc;
        $wx_store_res = $wx_store->update($wx_store_update);
        if (!$wx_store_res) {
            Log::info('添加分账接收方-更新状态失败');
        }

        return json_encode($data);
    }


    /**
     * 请求单次分账
     *
     * 单次分账请求按照传入的分账接收方账号和资金进行分账，同时会将订单剩余的待分账金额解冻给特约商户。故操作成功后，订单不能再进行分账，也不能进行分账完结
     * @param $data
     * @return string
     */
    public function profit_sharing($data)
    {
        sleep(60);
        $user_id = $data['user_id'];
        $out_trade_no = $data['out_trade_no'];
        $store_id = $data['store_id'];
        $options = $data['options'];
        $wx_sub_merchant_id = $data['wx_sub_merchant_id']; //微信支付分配的子商户号
        $transaction_id = $data['transaction_id']; //微信支付订单号
        $total_amount = $data['total_amount'] ?? 0; //订单总金额
        $ways_type = $data['ways_type'] ?? ''; //

        $mch_id = $options['payment']['merchant_id'];
        $appid = $options['app_id'];
        $key = $options['payment']['key'];
        $config = [
            'app_id' => $appid,
            'mch_id' => $mch_id,
            'key' => $key,
            'cert_path' => $options['payment']['cert_path'], // XXX: 绝对路径！！！！
            'key_path' => $options['payment']['key_path'], // XXX: 绝对路径！！！！
            'sub_mch_id' => $wx_sub_merchant_id,
            'sslCertPath' => $options['payment']['cert_path'], //
            'sslKeyPath' => $options['payment']['key_path'], //
        ];
        $payment = Factory::payment($config);

        if ($ways_type == '2000') {
            $wx_store_obj = WeixinStore::where('store_id', $store_id)->first();
            if (!$wx_store_obj) {
                return json_encode([
                    'status' => '2',
                    'message' => '分账接收方资料未设置'
                ]);
            }
        } elseif ($ways_type == '4000') {
            $wx_store_obj = WeixinaStore::where('store_id', $store_id)->first();
            if (!$wx_store_obj) {
                return json_encode([
                    'status' => '2',
                    'message' => '分账接收方资料未设置'
                ]);
            }
        } else {
            return json_encode([
                'status' => '2',
                'message' => '分账接收方资料未设置'
            ]);
        }

        $wx_sharing_account = $wx_store_obj->wx_sharing_account;
        $is_profit_sharing = $wx_store_obj->is_profit_sharing; //是否分账(0-不分;1-分)
        $wx_sharing_rate = $wx_store_obj->wx_sharing_rate;

        $fz_out_trade_no = 'wx_fz' . date('YmdHis', time()) . substr(microtime(), 2, 6) . sprintf('%03d', rand(0, 999)); //只能是数字、大小写字母_-|*@

        if ($is_profit_sharing) {
            if ($wx_sharing_rate > 0) {
                $fz_amount = $total_amount*$wx_sharing_rate; //分账金额,单位：分

                $wx_merchant_id = ($wx_store_obj->wx_sharing_type=='MERCHANT_ID') ? '商户' : '个人';

                $attributes = [
                    'mch_id' => $mch_id, //微信支付分配的商户号
                    'sub_mch_id' => $wx_sub_merchant_id,
                    'appid' => $appid, //微信分配的公众账号ID
                    'nonce_str' => md5(time().rand(1000, 9999)), //随机字符串，不长于32位
                    'sign_type' => 'HMAC-SHA256', //签名类型，目前只支持HMAC-SHA256
                    'transaction_id' => $transaction_id ?? '',
                    'out_order_no' => $fz_out_trade_no, //服务商系统内部的分账单号，在服务商系统内部唯一(单次分账、多次分账、完结分账应使用不同的商户分账单号),同一分账单号多次请求等同一次
                    'receivers' => json_encode([
                        [
                            'type' => $wx_store_obj->wx_sharing_type,
                            'account' => $wx_sharing_account,
                            'amount' => (int)$fz_amount,
                            'description' => '分到'. $wx_merchant_id
                        ]
                    ])
                ];

                $attributes['sign'] = $this->MakeSign($attributes, $key, 'HMAC-SHA256'); //签名
                $result = $this->postXmlCurl($config, $this->ToXml($attributes), 'https://api.mch.weixin.qq.com/secapi/pay/profitsharing', true);
                Log::info('微信分账，单次分账');
                Log::info($attributes);
                Log::info(self::xml_to_array($result));
                $result = self::xml_to_array($result);

                if ($result['return_code'] == 'SUCCESS') {
                    if ($result['result_code'] == 'SUCCESS') { //SUCCESS：分账申请接收成功，结果通过分账查询接口查询；FAIL ：提交业务失败
                        $profit_sharing_status = 1; //分账成功
                        $profit_sharing_status_desc = '分账申请接收成功';
                    } else {
                        $profit_sharing_status_desc = $result['err_code_des'] ?? '提交业务失败';
                    }

                    $data = [
                        'status' => 1,
                        'out_trade_no' => $out_trade_no
                    ];
                } else {
                    $profit_sharing_status_desc = $result['return_msg'] ?? '提交业务失败';
                    $data = [
                        'status' => 2,
                        'out_trade_no' => $out_trade_no,
                        'message' => $result['return_msg']
                    ];
                }

                $wx_sharing_insert = [
                    'store_id' => $store_id,
                    'out_trade_no' => $out_trade_no,
                    'fz_out_trade_no' => $fz_out_trade_no,
                    'fz_amount' => $fz_amount,
                    'wx_sharing_account' => $wx_sharing_account,
                    'total_amount' => $total_amount,
                    'fz_rate' => $wx_sharing_rate,
                ];
                if (isset($user_id)) $wx_sharing_insert['user_id'] = $user_id;
                if (isset($transaction_id)) $wx_sharing_insert['transaction_id'] = $transaction_id;
                if (isset($profit_sharing_status)) $wx_sharing_insert['status'] = $profit_sharing_status;
                if (isset($profit_sharing_status_desc)) $wx_sharing_insert['status_desc'] = $profit_sharing_status_desc;
                if (isset($profit_sharing_finish)) $wx_sharing_insert['is_finish'] = $profit_sharing_finish;
                if (isset($profit_sharing_finish_desc)) $wx_sharing_insert['is_finish_desc'] = $profit_sharing_finish_desc;
                $res = WeixinSharingOrder::create($wx_sharing_insert);
                if (!$res) {
                    Log::info($out_trade_no.'微信分账入库失败');
                    return json_encode([
                        'status' => '2',
                        'message' => '微信分账入库失败'
                    ]);
                }
            } else {
                //完结分账
                $profit_sharing_finish_data = [
                    'out_trade_no' => $out_trade_no,
                    'store_id' => $store_id,
                    'options' => $options,
                    'wx_sub_merchant_id' => $wx_sub_merchant_id,
                    'transaction_id' => $transaction_id,
                    'fz_out_trade_no' => $fz_out_trade_no,
                    'ways_type' => $ways_type
                ];
                $this->profit_sharing_finish($profit_sharing_finish_data);
            }

            return json_encode($data);
        } else {
            Log::info('门店：'.$store_id.'的订单：'.$out_trade_no.'分账比例为：'.$wx_sharing_rate.'开启分账：'.$is_profit_sharing);
        }

    }


    /**
     * 完结分账
     *
     * 1、不需要进行分账的订单，可直接调用本接口将订单的金额全部解冻给特约商户
     * 2、调用多次分账接口后，需要解冻剩余资金时，调用本接口将剩余的分账金额全部解冻给特约商户
     * 3、已调用请求单次分账后，剩余待分账金额为零，不需要再调用此接口。
     * @param $data
     * @return string
     */
    public function profit_sharing_finish($data)
    {
        $out_trade_no = $data['out_trade_no'];
        $store_id = $data['store_id'];
        $options = $data['options'];
        $wx_sub_merchant_id = $data['wx_sub_merchant_id']; //微信支付分配的子商户号
        $transaction_id = $data['transaction_id']; //微信支付订单号
        $fz_out_trade_no = $data['fz_out_trade_no']; //微信支付订单号
        $ways_type = $data['ways_type'] ?? ''; //

        $mch_id = $options['payment']['merchant_id'];
        $appid = $options['app_id'];
        $key = $options['payment']['key'];
        $config = [
            'app_id' => $appid,
            'mch_id' => $mch_id,
            'key' => $key,
            'cert_path' => $options['payment']['cert_path'], // XXX: 绝对路径！！！！
            'key_path' => $options['payment']['key_path'], // XXX: 绝对路径！！！！
            'sub_mch_id' => $wx_sub_merchant_id,
            'sslCertPath' => $options['payment']['cert_path'], //
            'sslKeyPath' => $options['payment']['key_path'], //
        ];
        $payment = Factory::payment($config);

        if ($ways_type == '2000') {
            $wx_store = WeixinStore::where('store_id', $store_id)->first();
            if (!$wx_store) {
                return json_encode([
                    'status' => '2',
                    'message' => '分账接收方资料未设置'
                ]);
            }
        } elseif ($ways_type == '4000') {
            $wx_store = WeixinaStore::where('store_id', $store_id)->first();
            if (!$wx_store) {
                return json_encode([
                    'status' => '2',
                    'message' => '分账接收方资料未设置'
                ]);
            }
        } else {
            return json_encode([
                'status' => '2',
                'message' => '分账接收方资料未设置'
            ]);
        }

        $attributes = [
            'mch_id' => $mch_id, //微信支付分配的商户号
            'sub_mch_id' => $wx_sub_merchant_id, //微信支付分配的子商户号
            'appid' => $appid, //微信分配的公众账号ID
            'nonce_str' => md5(time().rand(1000, 9999)), //随机字符串，不长于32位
            'sign_type' => 'HMAC-SHA256', //签名类型，目前只支持HMAC-SHA256
            'transaction_id' => $transaction_id ?? '', //微信支付订单号
            'out_order_no' => $fz_out_trade_no, //商户系统内部的分账单号，在商户系统内部唯一（单次分账、多次分账、完结分账应使用不同的商户分账单号），同一分账单号多次请求等同一次
            'description' => '分账已完成' //分账完结的原因描述
        ];
        $attributes['sign'] = $this->MakeSign($attributes, $key, 'HMAC-SHA256'); //签名
        $result = $this->postXmlCurl($config, $this->ToXml($attributes), 'https://api.mch.weixin.qq.com/secapi/pay/profitsharingfinish', true);
        Log::info('完结分账');
        Log::info(self::xml_to_array($result));
//        array (
//            'return_code' => 'SUCCESS',
//            'result_code' => 'FAIL',
//            'err_code' => 'ORDER_NOT_READY',
//            'err_code_des' => '订单处理中，暂时无法分账，请稍后再试',
//            'mch_id' => '1529340761',
//            'sub_mch_id' => '1603051502',
//            'appid' => 'wx71a6fa53625b7f85',
//            'nonce_str' => '8c43ec2dbf052dd6',
//            'sign' => '46A099E2BD3230D101A1EE175AC398486E2D97C3F83F4988A09188FF4379AA65',
//        )
        $result = self::xml_to_array($result);
        if ($result['return_code'] == 'SUCCESS') {
            if ($result['result_code'] == 'SUCCESS') {
                $profit_sharing_finish = 1;
                $profit_sharing_finish_desc = '分账申请接收成功';

                $data = [
                    'status' => 1,
                    'out_trade_no' => $out_trade_no
                ];
            } else {
                $profit_sharing_finish = 0;
                $profit_sharing_finish_desc = $result['err_code_des'] ?? '提交分账完结业务失败';

                $data = [
                    'status' => 2,
                    'out_trade_no' => $out_trade_no,
                    'message' => $result['return_msg']
                ];
            }
        } else {
            $profit_sharing_finish = 0;
            $profit_sharing_finish_desc = $result['return_msg'] ?? '提交分账完结业务失败';

            $data = [
                'status' => 2,
                'out_trade_no' => $out_trade_no,
                'message' => $result['return_msg']
            ];
        }
        $wx_sharing_order = WeixinSharingOrder::where('out_trade_no', $out_trade_no)->first();
        if ($wx_sharing_order) {
            $wx_sharing_update = [
                'profit_sharing_finish' => $profit_sharing_finish
            ];
            if (isset($profit_sharing_finish_desc)) $wx_sharing_update['is_finish_desc'] = $profit_sharing_finish_desc;
            $res = $wx_sharing_order::update($wx_sharing_update);
            if (!$res) {
                Log::info($out_trade_no.'微信完结分账入库失败');
                return json_encode([
                    'status' => '2',
                    'message' => '微信完结分账入库失败'
                ]);
            }
        } else {
            Log::info($out_trade_no.'微信分账订单未找到');
        }

        return json_encode($data);
    }


    /**
     * TODO:查询分账结果
     *
     * 发起分账请求后，可调用此接口查询分账结果；发起分账完结请求后，可调用此接口查询分账完结的执行结果。
     * 接口频率：80QPS
     * @param $data
     * @return string
     */
    public function profit_sharing_query($data)
    {

    }


}
